<?php

namespace App\Admin\Controllers;

use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Layout\Content;
use Illuminate\Support\Str;
use Encore\Admin\Tree;
use Encore\Admin\Layout\Column;
use Encore\Admin\Layout\Row;
use Encore\Admin\Widgets\Box;
class PermissionController extends AdminController
{
    protected function title()
    {
        return trans('admin.permissions');
    }

    /**
     * Index interface.
     *
     * @param Content $content
     *
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->title($this->title())
            ->description(trans('admin.list'))
            ->row(function (Row $row) {
                $row->column(6, $this->treeView()->render());

                $row->column(6, function (Column $column) {
                    $form = new \Encore\Admin\Widgets\Form();
                    $form->action(admin_url('auth/permissions'));

                    $permissionModel = config('admin.database.permissions_model');

                    $form->select('parent_id', trans('admin.parent_id'))->options($permissionModel::selectOptions());
                    $form->text('slug', trans('admin.slug'))->rules('required');
                    $form->text('name', trans('admin.name'))->rules('required');

                    $form->multipleSelect('http_method', trans('admin.http.method'))
                        ->options($this->getHttpMethodsOptions())
                        ->help(trans('admin.all_methods_if_empty'));
                    $form->textarea('http_path', trans('admin.http.path'));

                    $form->hidden('_token')->default(csrf_token());

                    $column->append((new Box(trans('admin.new'), $form))->style('success'));
                });
            });
    }

    /**
     * @return \Encore\Admin\Tree
     */
    protected function treeView()
    {
        $permissionModel = config('admin.database.permissions_model');

        $tree = new Tree(new $permissionModel());

        $tree->disableCreate();

        $tree->branch(function ($branch) {
            $payload = "<div class='pull-left' style='min-width:310px'><b>{$branch['name']}</b>&nbsp;&nbsp;[<span class='text-primary'>{$branch['slug']}</span>]";

            $path = array_filter(explode(PHP_EOL,str_replace(["\r\n","\n"],PHP_EOL,$branch['http_path'])));
            if (! $path) {
                return $payload.'</div>&nbsp;';
            }
            $max = 1;
            if (count($path) > $max) {
                $path = array_slice($path, 0, $max);
                array_push($path, '...');
            }
            $method = $branch['http_method'] ?: [];
            $path = collect($path)->map(function ($path) use (&$method) {
                if (Str::contains($path, ':')) {
                    [$me, $path] = explode(':', $path);

                    $method = array_merge($method, explode(',', $me));
                }
                if ($path !== '...' && ! empty(config('admin.route.prefix')) && ! Str::contains($path, '.')) {
                    $path = trim(admin_base_path($path), '/');
                }
                return "<code style='color:#4c60a3'>$path</code>";
            })->implode('&nbsp;&nbsp;');

            $method = collect($method ?: ['ANY'])->unique()->map(function ($name) {
                    return strtoupper($name);
                })->map(function ($name) {
                    return "<span class='label bg-primary'>{$name}</span>";
                })->implode('&nbsp;').'&nbsp;';

            $payload .= "</div>&nbsp; $method<a class=\"dd-nodrag\">$path</a>";

            return $payload;
        });

        return $tree;
    }

    /**
     * Edit interface.
     *
     * @param string  $id
     * @param Content $content
     *
     * @return Content
     */
    public function edit($id, Content $content)
    {
        return $content
            ->title($this->title())
            ->description(trans('admin.edit'))
            ->row($this->form()->edit($id));
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    public function form()
    {
        $permissionModel = config('admin.database.permissions_model');

        $form = new Form(new $permissionModel());

        $form->hidden('id', 'ID');
        $form->select('parent_id', trans('admin.parent_id'))->options($permissionModel::selectOptions());
        $form->text('slug', trans('admin.slug'))->rules('required');
        $form->text('name', trans('admin.name'))->rules('required');

        $form->multipleSelect('http_method', trans('admin.http.method'))
            ->options($this->getHttpMethodsOptions())
            ->help(trans('admin.all_methods_if_empty'));
        $form->textarea('http_path', trans('admin.http.path'));

        $form->hidden('created_at', trans('admin.created_at'));
        $form->hidden('updated_at', trans('admin.updated_at'));
        $form->tools(function (Form\Tools $tools){
            $tools->disableView();
        });
        return $form;
    }

    /**
     * Get options of HTTP methods select field.
     *
     * @return array
     */
    protected function getHttpMethodsOptions()
    {
        $model = config('admin.database.permissions_model');

        return array_combine($model::$httpMethods, $model::$httpMethods);
    }
}
